package example.com.dynamicproxy.AMSHook;

import android.content.Intent;
import android.os.Handler;
import android.os.Message;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author LiuYi
 *         创建时间： 2017/8/15.
 *         功能描述:
 */

public class ActivityThreadHandlerCallBack implements Handler.Callback {
    @Override
    public boolean handleMessage(Message msg) {
        int LAUNCH_ACTIVITY = 0;
        try {
            //获取LAUNCH_ACTIVITY的what值
            Class<?> clazz = Class.forName("android.app.ActivityThread$H");
            Field field = clazz.getField("LAUNCH_ACTIVITY");
            LAUNCH_ACTIVITY = field.getInt(null);

            //处理启动activity的消息
            if (msg.what == LAUNCH_ACTIVITY) {
                handleLaunchActivity(msg);
            }
        } catch (Exception e) {
        }

        return false;
    }

    private static void handleLaunchActivity(Message msg) {
        try {
            Object activityRecord = msg.obj;
            Field intentField = activityRecord.getClass().getDeclaredField("intent");
            intentField.setAccessible(true);
            Intent proxyIntent = (Intent) intentField.get(activityRecord);
            //拿到之前真实要被启动的Intent 然后把Intent换掉
            Intent originallyIntent = proxyIntent.getParcelableExtra("originallyIntent");
            if (originallyIntent == null) {
                return;
            }

            proxyIntent.setComponent(originallyIntent.getComponent());

            //todo:兼容AppCompatActivity，获取ActivityThread实例
            Class<?> forName = Class.forName("android.app.ActivityThread");
            Field field = forName.getDeclaredField("sCurrentActivityThread");//是android.app.ActivityThread的实例？
            field.setAccessible(true);
            Object activityThread = field.get(null);

            //调用activityThread.getPackageManager()获取该应用程序的PackageManager
            Method getPackageManager = activityThread.getClass().getDeclaredMethod("getPackageManager");
            Object iPackageManager = getPackageManager.invoke(activityThread);

            //生成该应用程序的PackageManager的动态代理，并替换之
            Class<?> iPackageManagerIntercept = Class.forName("android.content.pm.IPackageManager");
            Object proxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                    new Class<?>[]{iPackageManagerIntercept}, new PackageManagerHandler(iPackageManager));
            Field iPackageManagerField = activityThread.getClass().getDeclaredField("sPackageManager");  // 获取 sPackageManager 属性
            iPackageManagerField.setAccessible(true);
            iPackageManagerField.set(activityThread, proxy);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
